<script setup>
import {ref,onMounted,reactive,nextTick} from 'vue'
import {reqAllRoleList,reqAddOrUpdateRole,reqRemoveRole,reqAllMenuList,reqGetRolePermisstion,reqSetRolePermisstion} from '@/api/acl/role'
import useLayoutSettingStore from '@/store/setting'
import {ElMessage} from 'element-plus'

let pageNo = ref(1)  // 当前页
let pageSize = ref(10)  // 每页显示多少条数据
let total = ref(100)  // 一共有多少条数据
let keyword = ref('')  // 保存搜索关键字
let allRole = ref([])  // 保存从后端传过来的角色列表
let settingStore = useLayoutSettingStore()  // 控制刷新的仓库

let roleParams = reactive({  // 收集用户在 添加、编辑 角色信息时输入的信息
    id:0,
    name:'',
    permission_code:3,
})
let dialogVisite = ref(false)  // 控制 添加角色对话框 的显示与隐藏
let form = ref()  // 获取表单组件

let drawer = ref(false)  // 用来控制分配用户权限页面的显示与隐藏

let menuArr = ref([])  // 保存所有的权限菜单信息
let roleMenu = ref([])  // 保存单个角色的权限菜单
let tree = ref()  // 获取分配权限页面的树形组件实例


const getHasRole = (pager=1)=>{
    // 修改当前页码
    pageNo.value = pager
    reqAllRoleList(pageNo.value,pageSize.value,keyword.value).then(res=>{
        allRole.value = res.data.data
        total.value = res.data.total_num
    })
}
const getHasPermisstion = ()=>{
    reqAllMenuList().then(res=>{
        if(res.data.code==200){
            menuArr.value=res.data.data
        }else{
            ElMessage({
                type:'error',
                message:'获取菜单失败，'+res.data.msg
            })
        }
    })
}

onMounted(()=>{
    getHasRole()
    getHasPermisstion()
})

// 改变每页显示数量后触发的事件
const sizeChange = ()=>{
    getHasRole()
}
// 点击搜索按钮触发事件
const search = () => {
    getHasRole()
}
// 点击重置按钮触发事件
const reset = ()=>{
    settingStore.refsh = !settingStore.refsh
}

// 点击添加角色按钮触发事件
const addRole = ()=>{
    dialogVisite.value=true
    // 清空之前的数据
    Object.assign(roleParams,{
        id:0,
        name:'',
    })
    // 清空之前的表单校验错误提示信息
    nextTick(()=>{
        form.value.clearValidate('name')
    })

}
// 点击编辑角色按钮触发事件
const updateRole=(row)=>{
    dialogVisite.value=true
    // 清空之前的表单校验错误提示信息
    nextTick(()=>{
        form.value.clearValidate('name')
    })
    // 收集已有的数据
    Object.assign(roleParams,row)
}
// 角色信息 校验规则
// 角色名 校验方法
const validatorRoleName = (rule,value,callBack) =>{
    if( /^[A-Za-z0-9\u4e00-\u9fa5]{2,20}$/.test(value.trim())){
        callBack()
    }else{
        callBack(new Error('角色名称由 2-20 个字母、数字或汉字组成'))
    }
}
// 校验规则
const rules = {
    // props, require:true表示必填项，trigger:'blur'表示表单失去焦点验证，validator:validatorRoleName指定校验函数
    name:[ {require:true,trigger:'blur',validator:validatorRoleName} ]
}
// 添加、编辑角色dialog界面，点击确定按钮触发事件
const save = async ()=>{
    // 表单数据校验
    await form.value.validate()
    
    reqAddOrUpdateRole(roleParams).then(res=>{
        if(res.data.code==200){
            ElMessage({
                type:'success',
                message: roleParams.id? '编辑成功':'添加成功'
            })
            dialogVisite.value=false
            getHasRole(roleParams.id?pageNo.value:1)
        }else{
            ElMessage({
                type:'error',
                message:roleParams.id? '编辑失败，'+res.data.msg :'添加失败，'+res.data.msg
            })
        }
    })
}
// 点击 删除角色 按钮触发事件
const removeRole = (row)=> {
    reqRemoveRole(row.id).then(res=>{
        if(res.data.code==200){
            ElMessage({
                type:'success',
                message: '删除成功'
            })
            getHasRole(allRole.value.length > 1 ? pageNo.value : pageNo.value-1 )
        }else{
            ElMessage({
                type:'error',
                message:'删除失败，'+res.data.msg
            })
        }
    })
}

// 格式化用户的菜单列表，删除有子节点的项
const formatMenu = (allMenu,userMenu) => {
    allMenu.forEach(item=>{
        let index = userMenu.indexOf(item.id)
        if(  index > -1 && item.children && item.children.length>1){
            userMenu.splice(index,1)
            formatMenu(item.children,userMenu)
        }
    })
}
// 点击分配权限按钮触发事件
const setPermisstion = (row)=>{
    drawer.value=true
    // 收集当前要分配权限的角色信息
    Object.assign(roleParams,row)

    // 获取当前用户的权限菜单，当然在生成环境中最好用下面的方式发送网络请求获取
    roleMenu.value = row.menu
    if(roleMenu.value){
        formatMenu(menuArr.value,roleMenu.value)
    }
    nextTick(()=>{
        // 设置树形复选框 角色已有的权限
        tree.value.setCheckedKeys(roleMenu.value? roleMenu.value: [])
    })
    
    // 获取角色当前权限的数据
    // reqGetRolePermisstion(roleParams.id).then(res=>{
    //     roleMenu.value = res.data.data
    //     console.log(res.data);
    // })
}

// 指定树形控件具体显示 数据的 那个键值
const defaultProps = {
  children: 'children',
  label: 'name',
}

// 分配权限页面-点击确定按钮触发事件
const confirmClick = ()=>{
    // 获取当前选中的权限
    let arr = tree.value.getCheckedKeys()
    let halfArr = tree.value.getHalfCheckedKeys()
    arr = arr.concat(halfArr)
    // console.log(arr);
    // return
    let data = {
        role_id:roleParams.id,
        menu:arr
    }
    reqSetRolePermisstion(data).then(res=>{
        if(res.data.code==200){
            
            ElMessage({
                type:'success',
                message:'修改成功'
            })
            drawer.value = false  // 关闭抽屉组件
            // 修改本地数据
            allRole.value.forEach(item=>{
                if(item.id==roleParams.id){
                    item.menu=arr
                }
            })
            // 或者也可以重新从服务器请求数据，这能增加准确性，但也会改服务器带来一定的压力
            // getHasRole(pageNo.value)
        }else{
            ElMessage({
                type:'error',
                message:'分配失败，'+res.data.msg
            })
        }
    })
}


</script>

<template>
    <div class="box">
        <el-card style="height: 80px;">
            <el-form :inline="true" class="form">
                <el-form-item label="角色搜索">
                    <el-input placeholder="请输入要搜索的角色关键字" v-model="keyword"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="search" :disabled="keyword?false:true">搜索</el-button>
                    <el-button type="primary" @click="reset">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <el-card style="margin: 10px 0;">
            <el-button v-has="`btn.Role.add`" type="primary" icon="Plus" @click="addRole">添加角色</el-button>
            <el-table border style="margin: 10px 0;" :data="allRole">
                <el-table-column type="index" align="center" label="#"></el-table-column>
                <el-table-column label="id" prop="id"></el-table-column>
                <el-table-column label="角色名称" prop="name" show-overflow-tooltip></el-table-column>
                <el-table-column label="创建时间" prop="create_time" show-overflow-tooltip></el-table-column>
                <el-table-column label="更新时间" prop="update_time" show-overflow-tooltip></el-table-column>
                <el-table-column width="280px" label="操作" fixed="right">
                    <template #="{row,$index}">
                        <el-button v-has="`btn.Role.setPremisstion`" type="primary" size="small" icon="User" @click="setPermisstion(row)">分配权限</el-button>
                        <el-button v-has="`btn.Role.edit`" type="primary" size="small" icon="Edit" @click="updateRole(row)">编辑</el-button>
                        <el-popconfirm :title="`你确定要 ${row.name} 角色吗？`" width="260px" @confirm="removeRole(row)">
                            <template #reference>
                                <el-button v-has="`btn.Role.delete`" type="primary" size="small" icon="Delete">删除</el-button>
                            </template>
                        </el-popconfirm>
                        
                    </template>
                </el-table-column>

            </el-table>

            <!-- 分页器 -->
            <el-pagination
                v-model:current-page="pageNo"
                v-model:page-size="pageSize"
                :page-sizes="[10, 20, 30, 50]"
                background
                layout="prev, pager, next, jumper,->,total, sizes"
                :total="total"
                @current-change="getHasRole"
                @size-change="sizeChange"
                />
        </el-card>

        <!-- 添加或修改角色组件 -->
        <el-dialog v-model="dialogVisite" :title="roleParams.id?'编辑角色':'添加角色'">
            <el-form :model="roleParams" :rules="rules" ref="form">
                <el-form-item label="角色名称" prop="name">
                    <el-input placeholder="请输入角色名称" v-model="roleParams.name"></el-input>
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="dialogVisite = false">取消</el-button>
                <el-button type="primary" @click="save">确定</el-button>
            </template>
        </el-dialog>

        <!-- 抽屉组件，用来分配用户的权限 -->
        <el-drawer v-model="drawer" direction="rtl" >
            <template #header>
                <h4>分配菜单与按钮的权限</h4>
            </template>
            <template #default>
                <!-- 树形控件 -->
                <el-tree ref="tree" :data="menuArr" show-checkbox node-key="id" default-expand-all
                    :default-checked-keys="roleMenu" :props="defaultProps"
                />
            </template>
            <template #footer>
                <div>
                    <el-button @click="drawer=false">取消</el-button>
                    <el-button type="primary" @click="confirmClick">确定</el-button>
                </div>
            </template>
        </el-drawer>
    </div>
</template>

<style scoped lang="scss">
.form{
    display: flex;
    justify-content: space-between;
    align-items: center;
}
</style>